import os
import docx
from pathlib import Path
import docx.dml
import zipfile
import json
import tempfile
from loguru import logger

class replacer:
    def check_need_replace(self, file_name:str) -> bool:
        if not file_name.endswith(".docx"):
            return False 
        for word in self.replace_word.keys():
            if word in file_name:
                return True
        return False

    def __replace_word(self, input:str):
        for key , value in self.replace_word.items():
            if key in input:
                logger.debug(key)
                input = input.replace(key,value)
        return input
    
    def __load_config(self, config_path:Path = Path(__file__).parent / "config/config.json"):
        with open(config_path,'r',encoding="utf-8") as json_file:
            config:dict = json.loads(''.join(json_file))
            self.replace_word:dict = config.get("replace_word",{})
            self.output_name:str = config.get("output_name","output.zip")

    def __unzip_files(self,input_path:str,output_dir:str)->str:
        with zipfile.ZipFile(input_path) as zip_file:
            zip_file.extractall(output_dir)
        logger.debug(output_dir)
        return output_dir


    def __process_docx(self, target_dir:str)->list:
        
        targets:list[Path] = list()
        replaced_path:list[str] = list()
        

        for root, dirs, files in os.walk(target_dir):
            for file in files:
                if not self.check_need_replace(file):
                    continue
                targets.append(Path(root) / file)

        logger.debug(targets)

        for file_path in targets:
            doc = docx.Document(file_path)
            # paragraphs        
            for paragraph in doc.paragraphs:
                if paragraph.text in self.replace_word.keys():
                    paragraph.text = self.__replace_word(paragraph.text)

            # tables
            for table in doc.tables:
                for row in table.rows:
                    for cell in row.cells:
                        if cell.text in self.replace_word.keys():
                            cell.text = self.__replace_word(cell.text)

            # save
            new_name = self.__replace_word(file_path.name)
            save_path = file_path.parent / new_name
            doc.save(save_path)
            replaced_path.append(save_path)

        return replaced_path

    @staticmethod
    def __zip_result(targets:list[Path],out_path:Path)->str:
        #zip
        with zipfile.ZipFile(out_path.absolute(), 'w') as zipf:
            for target in targets:
                zipf.write(target.absolute(),target.name)
    
        return out_path
        

    def run(self, input_path:str, output_path:str):
        self.__load_config()
        with tempfile.TemporaryDirectory() as tempdir:
            unziped_dir = self.__unzip_files(input_path,tempdir.__str__())

            replaced_path = self.__process_docx(unziped_dir)
            
            output_path = Path(output_path) / self.output_name
            
            result_path = self.__zip_result(replaced_path,output_path)
            logger.success(result_path)
        logger.info("exit")


# 单元测试
#replacer().run(R"C:\Users\MI\Documents\WeChat Files\wxid_5oyy30r35zso12\FileStorage\File\2024-10\陈晨\陈晨\陈晨.zip",R"C:\Users\MI\Desktop")